<template>
  <div class="edit-align-line">
    <div
      class="line"
      v-for="item in line.lineArr"
      :key="item"
      :class="[
        item.includes('row') ? 'row' : 'col',
        line['select'].has(item) && 'visible',
      ]"
      :style="useComponentStyle(line['select'].get(item))"
    ></div>
  </div>
</template>

<script setup>
import { reactive, computed, watch } from "vue";
import store from "@/store";
import { throttle } from "lodash";

// * 吸附距离
const minDistance = 5;
// * 线条集合
const line = reactive({
  // 行横向row（上中下），列竖线col（左中右）
  lineArr: ["rowt", "rowc", "rowb", "coll", "colc", "colr"],
  // 展示线
  select: new Map(),
  // 已经吸附
  sorptioned: {
    x: false,
    y: false,
  },
});

// * 位置计算
const useComponentStyle = (attr) => {
  if (!attr) return {};
  return {
    left: `${attr.x ? attr.x : 0}px`,
    top: `${attr.y ? attr.y : 0}px`,
  };
};

let selectedComponent = computed(() => {
  return store.state.chartEditStore.selectedComponent;
});

let renderComponentList = computed(() => {
  return store.state.chartEditStore.renderComponentList;
});

// * 是否开始计算
const isDrag = computed(() => {
  return store.state.chartEditStore.editCanvas.isDrag;
});

// * 吸附判定
const isSorption = (selectValue, componentValue) => {
  const isSorption = Math.abs(selectValue - componentValue) <= minDistance;
  return isSorption;
};

watch(
  () => selectedComponent.value.attr,
  throttle(() => {
    if (isDrag.value) {
      //正在拖动
      let w = selectedComponent.value.attr.w,
        h = selectedComponent.value.attr.w;
      let xl = selectedComponent.value.attr.x,
        xc = xl + w / 2,
        xr = xl + w,
        yt = selectedComponent.value.attr.y,
        yc = yt + h / 2,
        yb = yt + h;

      line.select.clear();
      line.lineArr.forEach((lineItem) => {
        renderComponentList.value.forEach((comp) => {
          if (comp.id === selectedComponent.value.id) return;

          let cxl = comp.attr.x,
            cxc = cxl + comp.attr.w / 2,
            cxr = cxl + comp.attr.w,
            cyt = comp.attr.y,
            cyc = cyt + comp.attr.h / 2,
            cyb = cyt + comp.attr.h;
          // 横线对比的是 Y
          if (lineItem.includes("rowt")) {
            // 顶部
            if (isSorption(yt, cyt)) {
              line.select.set(lineItem, { y: cyt });
              selectedComponent.value.attr.y = cyt;
            }
            if (isSorption(yt, cyc)) {
              line.select.set(lineItem, { y: cyc });
              selectedComponent.value.attr.y = cyc;
            }
            if (isSorption(yt, cyb)) {
              line.select.set(lineItem, { y: cyb });
              selectedComponent.value.attr.y = cyb;
            }
          }
          if (lineItem.includes("rowc")) {
            // 顶部
            if (isSorption(yc, cyt)) {
              line.select.set(lineItem, { y: cyt });
              selectedComponent.value.attr.y = cyt - h / 2;
            }
            if (isSorption(yc, cyc)) {
              line.select.set(lineItem, { y: cyc });
              selectedComponent.value.attr.y = cyc - h / 2;
            }
            if (isSorption(yc, cyb)) {
              line.select.set(lineItem, { y: cyb });
              selectedComponent.value.attr.y = cyb - h / 2;
            }
          }
          if (lineItem.includes("rowb")) {
            // 顶部
            if (isSorption(yb, cyt)) {
              line.select.set(lineItem, { y: cyt });
              selectedComponent.value.attr.y = cyt - h;
            }
            if (isSorption(yb, cyc)) {
              line.select.set(lineItem, { y: cyc });
              selectedComponent.value.attr.y = cyc - h;
            }
            if (isSorption(yb, cyb)) {
              line.select.set(lineItem, { y: cyb });
              selectedComponent.value.attr.y = cyb - h;
            }
          }

          // 纵线对比的是 X
          if (lineItem.includes("coll")) {
            if (isSorption(xl, cxl)) {
              line.select.set(lineItem, { x: cxl });
              selectedComponent.value.attr.x = cxl;
            }
            if (isSorption(xl, cxc)) {
              line.select.set(lineItem, { x: cxc });
              selectedComponent.value.attr.x = cxc;
            }
            if (isSorption(xl, cxr)) {
              line.select.set(lineItem, { x: cxr });
              selectedComponent.value.attr.x = cxr;
            }
          }
          if (lineItem.includes("colc")) {
            if (isSorption(xc, cxl)) {
              line.select.set(lineItem, { x: cxl });
              selectedComponent.value.attr.x = cxl - w / 2;
            }
            if (isSorption(xc, cxc)) {
              line.select.set(lineItem, { x: cxc });
              selectedComponent.value.attr.x = cxc - w / 2;
            }
            if (isSorption(xc, cxr)) {
              line.select.set(lineItem, { x: cxr });
              selectedComponent.value.attr.x = cxr - w / 2;
            }
          }
          if (lineItem.includes("colr")) {
            if (isSorption(xr, cxl)) {
              line.select.set(lineItem, { x: cxl });
              selectedComponent.value.attr.x = cxl - w;
            }
            if (isSorption(xr, cxc)) {
              line.select.set(lineItem, { x: cxc });
              selectedComponent.value.attr.x = cxc - w;
            }
            if (isSorption(xr, cxr)) {
              line.select.set(lineItem, { x: cxr });
              selectedComponent.value.attr.x = cxr - w;
            }
          }
        });
      });
    } else {
      //停止拖动
    }
  }, 200),
  { deep: true }
);

// * 取消对齐线
watch(isDrag, (val) => {
  !val && line.select.clear();
});
</script>

<style lang="scss" scoped>
.edit-align-line {
  .line {
    z-index: 1;
    position: absolute;
    top: 0;
    left: 0;
    display: none;
    border-width: 1px;
    border-style: solid;
    border-color: #51d6a9;
    opacity: 0.7;
    &.visible {
      display: block;
    }
  }
  .row {
    width: 100%;
  }
  .col {
    height: 100%;
  }
}
</style>
